#include <string.h>
#include <iostream>
using std::cout;
using std::ostream;
using std::endl;

class SSOString{
public:
    SSOString()
    :_size(0)
    {
        //空字符串时，长度小于15，字符存储的位置和string对象的位置相同的
        //应该去使用_array，所以全部填充0即可
        memset(_buffer._array, 0, sizeof(_buffer._array));
    }

    SSOString(const char * pstr)
    :_size(strlen(pstr))
    {
        //判断长度究竟是小于等于15还是大于15
        if(_size <= 15){
            //_array
            memset(_buffer._array, 0, sizeof(_buffer._array));
            strcpy(_buffer._array, pstr);
        }else {
            //否则使用_pointer
            _buffer._pointer = new char[_size + 1]();
            strcpy(_buffer._pointer, pstr);
        }
    }

    //析构函数里面需要做哪些事情？？？？
    //判断长度是否大于15，如果大于15，则需要回收堆空间
    //其他时候不需要去处理
    ~SSOString(){
        if(_size > 15){
            if(_buffer._pointer){
                delete [] _buffer._pointer;
                _buffer._pointer = nullptr;
            }
        }
    }

    //拷贝构造函数
    SSOString(const SSOString & rhs)
    :_size(rhs._size)
    {
        if(_size <= 15){
            memset(_buffer._array, 0, sizeof(_buffer._array));
            strcpy(_buffer._array, rhs._buffer._array);
        }else {
            _buffer._pointer = new char[_size + 1]();
            strcpy(_buffer._pointer, rhs._buffer._pointer);
        }
    }


    //赋值运算符函数
    //左是15以内，右是15以内:直接处理_array即可
    //左是15以内，右是15以外:左清空;使用_pointer执行深拷贝
    //左是15以外，右是15以内:左回收资源;使用_array
    //左是15以外，右是15以外:标准的赋值运算符操作:先回收左操作数空间，执行深拷贝(_pointer)
    SSOString & operator=(const SSOString & rhs){
        if(this != &rhs){

            if(_size <= 15){
                memset(_buffer._array, 0, sizeof(_buffer._array));
            }else {
                //左操作数的字符长度大小大于15
                delete [] _buffer._pointer;
            }

            if(rhs._size <= 15){
                strcpy(_buffer._array, rhs._buffer._array);
            }else {
                _buffer._pointer = new char[rhs._size + 1]();
                strcpy(_buffer._pointer, rhs._buffer._pointer);
            }
            _size = rhs._size;
        }
        return *this;
    }

    friend ostream & operator<<(ostream & os, const SSOString & rhs);

private:
    //每次只可以使用一个数据成员
    //比如当前使用了_array，那么就不可以再次使用_pointer
    union Buffer{
        char * _pointer;
        char _array[16];
    };

    Buffer _buffer;
    int _size;
};
//重载输出流运算符
//输出string对象里面的字符信息
//但是现在需要做的事情是需要区分究竟是小于等于15还是大于15
ostream & operator<<(ostream & os, const SSOString & rhs){
    if(rhs._size <= 15){
        os << rhs._buffer._array;
    }else {
        os << rhs._buffer._pointer;
    }
    return os;
}

void test(){
    SSOString str;
    cout << str << endl;
    SSOString str2("hello");
    cout << str2 << endl;
    SSOString str3("hello,world,hello,python");
    cout << str3 << endl;
}
void test2(){
    SSOString str("hello");
    SSOString str2 = str;
    cout << str2 << endl;

    SSOString str3("hello,worldf,hello,python");
    SSOString str4 = str3;
    cout << str4 << endl;
}
void test3(){
    //赋值运算符测试
    SSOString str("hello");
    SSOString str2("hello,world,hello,python");
    //str = str2;
    str2 = str;
    cout << str2 << endl;
    SSOString str3("hello,world,helloxsssssssssss");
    SSOString str4("worldi,ssssssssssssssssssssss");
    str3 = str4;
    cout << str3 << endl;
}

int main()
{
    test3();
    return 0;
}

